﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace UD650_IMG_CSharp
{
    public partial class Form1 : Form
    {
        public IPEndPoint ipe;
        Socket socket;
        public Form1()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Start();
            try
            {
                IPAddress ip = IPAddress.Parse(txtIp.Text);
                ipe = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));

                Thread worker = new Thread(DoWork);
                worker.IsBackground = true;
                worker.Start();

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void DoWork()
        {
            while (true)
            {
                try
                {

                    DateTime lastRequestTime = DateTime.Now;
                    socket = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                    socket.NoDelay = false;
                    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, true);
                    socket.ReceiveTimeout = 30 * 1000;
                    socket.Connect(ipe);
                    appendText("已经连接到服务端....");

                    byte[] bytes1 = new byte[1024];
                    //while (true)
                    //{
                    //    int RecvByteLen = socket.Receive(bytes1);
                    //    //if (RecvByteLen == 0)
                    //    //{
                    //    //    continue;
                    //    //}
                    //    appendText(string.Format("接收到字节长度:{0}", RecvByteLen));

                    //}
                    while (true)
                    {
                        byte[] bData = new byte[16];
                        //bData[0] = (byte)0x01;
                        System.Text.Encoding.Default.GetBytes("160526064005BD");
                        socket.Send(BuildPack((byte)0x01, bData, bData.Length));
                        Thread.Sleep(10000);
                    }

                }
                catch (Exception ex)
                {
                    appendText(ex.Message);
                }
                finally
                {
                    if (socket != null)
                    {
                        try
                        {
                            this.socket.Shutdown(SocketShutdown.Both);
                        }
                        catch (Exception ex)
                        {
                            appendText(ex.Message + "\r\n" + ex.StackTrace.ToString());
                        }

                        this.socket.Close();
                    }
                    Thread.Sleep(3000);
                }
            }

        }

        public string lastLogText = "";
        /// <summary>
        /// 添加到日志
        /// </summary>
        /// <param name="log">日志信息</param>
        private void appendText(string log, bool save = true)
        {
            Action<string> actionDelegate = (x) =>
            {
                if (this.richTextBox1.Text.Length > 20000)
                {
                    this.richTextBox1.Text = this.richTextBox1.Text.Substring(20000, this.richTextBox1.Text.Length - 20000);
                }
                this.richTextBox1.AppendText(DateTime.Now.ToString() + ":" + log);
                richTextBox1.AppendText(System.Environment.NewLine);
                this.richTextBox1.ScrollToCaret();
            };
            this.richTextBox1.Invoke(actionDelegate, log);
        }
        /// <summary>
        /// 组装包，待发给客户端
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="bData"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public byte[] BuildPack(byte cmd, byte[] bData, int len)
        {
            int PackSize = len + 8;
            if (PackSize < 24) PackSize = 24;

            byte[] PackBuf = new byte[PackSize];
            for (int i = 0; i < PackSize; i++)
            {
                PackBuf[i] = 0;
            }

            PackBuf[0] = (byte)0xDD;
            PackBuf[1] = (byte)0xCC;
            PackBuf[2] = (byte)0; //bAddress
            PackBuf[3] = (byte)cmd;
            PackBuf[4] = (byte)(len & 0xff);
            PackBuf[5] = (byte)((len >> 8) & 0xff);
            for (int i = 0; i < len; i++)
            {
                PackBuf[i + 6] = bData[i];
            }
            int checknum = CheckSum(PackBuf, PackSize - 2);
            PackBuf[len + 6] = (byte)(checknum & 0xff);
            PackBuf[len + 7] = (byte)(((checknum & 0xFFFF) >> 8) & 0xff);
            return PackBuf;
        }
        //public byte[] BuildPack(byte cmd, byte[] bData, int len)
        //{
        //    int PackSize = len + 8 + 4;
        //    if (PackSize < 24) PackSize = 24;

        //    byte[] PackBuf = new byte[PackSize];
        //    for (int i = 0; i < PackSize; i++)
        //    {
        //        PackBuf[i] = 0;
        //    }

        //    PackBuf[0] = (byte)0xDD;
        //    PackBuf[1] = (byte)0xCC;
        //    PackBuf[2] = (byte)2; //address。2是560设备,860是16
        //    PackBuf[3] = (byte)cmd;
        //    PackBuf[4] = (byte)(len & 0xff);
        //    PackBuf[5] = (byte)((len >> 8) & 0xff);
        //    PackBuf[6] = (byte)((len >> 16) & 0xff);
        //    PackBuf[7] = (byte)((len >> 24) & 0xff);
        //    for (int i = 0; i < len; i++)
        //    {
        //        PackBuf[i + 8] = bData[i];
        //    }
        //    int checknum = CheckSum(PackBuf, PackSize - 4);
        //    PackBuf[len + 8] = (byte)(checknum & 0xff);
        //    PackBuf[len + 9] = (byte)(((checknum & 0xFFFF) >> 8) & 0xff);
        //    //预防cheknum比较大，2个byte存不下的情况
        //    PackBuf[len + 10] = (byte)(((checknum & 0xFFFF) >> 16) & 0xff);
        //    PackBuf[len + 11] = (byte)(((checknum & 0xFFFF) >> 24) & 0xff);
        //    return PackBuf;
        //}

        /// <summary>
        /// 校验和
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public static int CheckSum(byte[] buf, int len)
        {
            int Sum = 0;
            int i;

            for (i = 0; i < len; i++)
            {
                Sum += buf[i] & 0xff;
            }
            return Sum & 0xffff;
        }


        private void timer1_Tick(object sender, EventArgs e)
        {
            // 打开设备
            byte[] comApiVer = new byte[100];
            Program.TG_GetComApiVer(comApiVer);
            string str = System.Text.Encoding.Default.GetString(comApiVer);
            Console.WriteLine("API Version is {0}", str);

            //检测设备
            int UDisk = 0;
            int Hid = 0;
            int devNum = 0;
            devNum = Program.TG_DetectDev(ref UDisk, ref Hid);
            if (0 == devNum)
            {
                Console.WriteLine("没有发现指静脉USB设备");
                return;
            }
            Console.WriteLine("检测到的设备数为{0}", devNum);

            //连接设备
            int i_ret = -1;
            IntPtr m_hDevHandle = IntPtr.Zero;
            byte m_u8DevAddress = 0;
            byte[] password = System.Text.Encoding.Default.GetBytes("00000000");
            int pwLen = 8;
            i_ret = Program.TG_ConnectDev(0, 0, m_u8DevAddress, password, pwLen, ref m_hDevHandle);
            if (i_ret != ErrorCode.XG_ERR_SUCCESS)
            {
                Console.WriteLine("XG_ConnectDev Error {0}", i_ret);
                return;
            }

            //byte[] fv_data = new byte[500 * 300];
            byte[] fv_data = new byte[320 * 140];
            int width = 0;
            int height = 0;
            byte[] pChara = new byte[8192];
            int pSize = 0;

            Console.WriteLine("请自然轻放手指");
            //Program.speak(m_u8DevAddress, m_hDevHandle, SoundCode.FV_V_INPUT_FINGE, SoundCode.FV_V_ASYN);
            while (true)
            {
                

                // 判断是否放入手指
                i_ret = Program.TG_GetFingerStatus(m_u8DevAddress, m_hDevHandle);
                if (i_ret <= 0)
                {
                    continue;
                }


                i_ret = Program.TG_GetDeviceVeinBmp(m_hDevHandle, fv_data, ref width, ref height, pChara, ref pSize);
                if (ErrorCode.XG_ERR_SUCCESS != i_ret)
                {
                    continue;
                }
                var bData = fv_data;
                if (socket != null)
                {
                    Thread.Sleep(100);
                    Console.WriteLine("发送指静脉采集特征给服务端");
                    try
                    {
                        socket.Send(BuildPack((byte)0x0F, bData, bData.Length));
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("发送失败."+ex.Message);
                    }
                }
                Console.WriteLine("采集图像成功!");
                Console.WriteLine("图像宽度{0}", width);
                Console.WriteLine("图像高度{0}", height);
                Thread.Sleep(3000);
                break;
            }

            // 断开设备
            Program.TG_Disconnect(m_u8DevAddress, m_hDevHandle);
            Program.TG_CloseDev(m_u8DevAddress, m_hDevHandle);


            //char ch;
            //ch = (char)Console.Read(); // get a char
        }
    }
}
